﻿using System;
using System.Collections.Generic;
using System.Linq;
using Ext.Net;
using Ext.Net.Utilities;
using KamLib.Controls;


namespace KamLib
{

    public static class RecordWindowFormAdapter
    {
        public static void Apply(IRecordWindowContainer wc, IRecordFormContainer fc, bool creating)
        {
            if (!creating) return;
            if (wc.ValidStatus != null)
                wc.ValidStatus.FormPanelID = fc.Form.ID;
        }
    }

    public static class RecordWindowFormLogicAdapter
    {
        public static void Apply(FormLogic logic, IRecordWindowContainer wc, IRecordFormContainer fc)
        {
            if (!logic.Creating) return;

            var wnd = wc.Wnd;
            var frmid = fc.Form.ClientID;

            var preRendered = false;
            wnd.PreRender += (sender, ev) =>
            {
                if (preRendered) return;
                preRendered = true;
                var localDetails = new List<string>();
                foreach (var d in logic.Details.Where(a => a.Logic is ListLogic && !string.IsNullOrEmpty(a.JsonListField)))
                {
                    if (d.Logic.EquipContainer == null) continue;
                    var istore = d.Logic.EquipContainer.Get<IStoreContainer>();
                    if (istore == null) continue;
                    localDetails.Add("{field:'" + d.JsonListField + "',store:" + istore.Store.ClientID + "}");
                }
                wnd.Listeners.AfterRender.Handler +=
                    "KamLib.Logic.Form.register(" + logic.Key +
                    ", { wnd: this, form: " + frmid +
                        ", validStatus: " + (wc.ValidStatus != null ? wc.ValidStatus.ClientID : "null") +
                        ", localDetails: [" + string.Join(",", localDetails) + "]" +
                    " });";
            };
            wnd.Listeners.BeforeDestroy.Handler +=
                "KamLib.Logic.Form.unregister(" + frmid + ");";
            if (wc.CanReload && wc.cmdReload != null)
                wc.cmdReload.OnClientClick = "KamLib.Logic.Form.load(" + frmid + ");";
            if (wc.CanSave)
            {
                if (wc.cmdApply != null)
                    wc.cmdApply.OnClientClick = "KamLib.Logic.Form.save(" + frmid + ");";
                if (wc.cmdOK != null)
                    wc.cmdOK.OnClientClick = "KamLib.Logic.Form.save(" + frmid + ", true);";
            }
            wc.cmdClose.OnClientClick = "if (!KamLib.Logic.Form.closeForm(" + frmid + ")) " + wnd.ClientID + ".close();";

            if (logic.Key != null && logic.Key.MasterKey != null)
                wnd.Tools.Add(new Tool
                {
                    Type = ToolType.Up,
                    Handler = "KamLib.Logic.Form.showMaster(" + frmid + ")",
                    Qtip = "Go to " + logic.Controller.Context.GetEntityDesc(logic.Key.MasterKey).Name,
                });

            if (logic.IsLocal)
                wnd.CloseAction = CloseAction.Hide;
        }
    }


    public abstract class WindowFormLogicControl : LogicControl, IFormLogicContainer
    {
        public new FormLogic Logic { get { return (FormLogic)base.Logic; } set { base.Logic = value; } }
        private readonly EquipInterfaceContainer iContainer = new EquipInterfaceContainer();
        public EquipInterfaceContainer Owner { get { return iContainer; } set { } }

        public Window _Wnd;
        public FormPanel _Form;


        public override void Initialize()
        {
            _Wnd = FindControl(Logic.FormWindowID) as Window;
            if (_Wnd == null)
                throw new Exception("Can't find Window with id '" + Logic.FormWindowID + "' on '" + ClientID + "'.");

            _Form = _Wnd.FindControl(Logic.FormID) as FormPanel;
            if (_Form == null)
                throw new Exception("Can't find FormPanel with id '" + Logic.FormID + "' on '" + ClientID + "'.");

            Logic.EquipContainer = iContainer;
            iContainer.Register(this);
            var fc = iContainer.Register(new RecordFormLogicContainer(Logic) { Form = _Form });
            var wc = iContainer.Register(new RecordWindowLogicContainer(Logic) { Wnd = _Wnd });

            RecordWindowEquiper.Apply(wc, Logic.Creating);
            RecordFormEquiper.Apply(fc, Logic.Creating);
            RecordWindowFormAdapter.Apply(wc, fc, Logic.Creating);
            RecordWindowFormLogicAdapter.Apply(Logic, wc, fc);

            if (Logic.Creating)
            {
                var fieldInfos = Logic.FieldInfos;
                if (fieldInfos != null)
                {
                    foreach (var field in ControlUtils.FindControls<Field>(_Form))
                    {
                        var adapter = field as IUiFormFieldInfoAdapter;
                        if (adapter == null) continue;
                        var info = fieldInfos.FirstOrDefault(a => string.Equals(a.Name, field.Name));
                        if (info == null) continue;
                        adapter.Apply(info);
                    }
                }
            }

            base.Initialize();
        }

        public GridPanel GetGrid(string id)
        {
            var f = GetType().GetPropertyOrField(id);
            if (f == null)
                throw new ArgumentException("The field or property 'GridPanel " + id + "' is not founds.");

            return (GridPanel)f.GetValue(this, null);
        }

    }

}